<?php
class AccountService extends ServiceBase
{   
    /**
    * Register an user
    *
    * @param mixed $params
    * @return ServiceResult
    */
    public function register($params)
    {
        $user = new User();        
        self::getModel($params, $user, 'register');
        
        if (self::$result->isFailed())
            return self::$result;

        $user->Avatar = CUploadedFile::getInstance($user, 'Avatar');
       
        $user->CreatedDate = date('Y/m/d H:i:s', time());

        // Keep raw password to send mail to user        
        $rawPassword = $user->Password;
        
        //Encrypt password
        $user->Password = md5($user->Password);
        $user->rePassword = md5($user->rePassword);
        
        //Validation info just in case it is used
        $user->ValidationCode = md5(time());
        $user->ValidationType = User::VALIDATION_TYPE_ACTIVATE;
        $user->Status = User::STATUS_INACTIVE;

        //Set primarykey to null in order to recieve auto increase ID from DB
        $user->Id = null;
        
        try {                       
            // Save to db
            if ($user->save()) {
                // Save user categories
                $categories = $params['Categories'];
                if (defined(UserSettings::REGISTERED_USER_ROLES)) {
                    
                    $categories = array_merge($categories, array(UserSettings::REGISTERED_USER_ROLES));
                }
                foreach ($categories as $categoryId) {
                    $userCat = new UserCategory();
                    $userCat->UserId = $user->Id; 
                    $userCat->CategoryId = $categoryId;
                    if(!$userCat->save()) {
                        self::$result->setFailStatus(ServiceResult::ERR_INVALID_DATA, self::normalizeModelErrors($userCat->getErrors()));
                    }
                }
                // Check newsletter subscriber
                $receiveNewsletter = $user->ReceiveNewsletter;
                if (! empty($receiveNewsletter)) {
                    Yii::import('Messaging.models.Subscriber');
                    // Check if this email exists
                    $tempSub = Subscriber::model()->find('Email=:email', array(':email'=>$user->Email));
                    if (empty($tempSub)) {
                        $subscriber = new Subscriber();
                        $subscriber->Email = $user->Email;
                        $subscriber->SubscribedDate = date('Y-m-d H:i:s');
                        $subscriber->save();
                    }
                }
                
                self::sendRegisterMail($user, $rawPassword);
            }
        } catch (CException $ex) {
            Yii::log($ex->getMessage(), CLogger::LEVEL_INFO);
            self::$result->ReturnedData['User'] = $user; 
            self::$result->setFailStatus(ServiceResult::ERR_INVALID_DATA, self::normalizeModelErrors($user->Errors));
        }
        self::$result->ReturnedData['User'] = $user; 
        return self::$result;
    }
    
    /**
    * Send email when register
    *     
    * @param mixed $params
    * @return result
    */
    public function sendRegisterMail($user, $rawPassword) 
    {
        Yii::import('Messaging.services.EmailService');        
        EmailService::init('Messaging');       
                 
        $email = new Email();
        $email->Subject = Yii::t('User', 'REGISTER_EMAIL_SUBJECT');
        $email->From = Settings::ADMIN_EMAIL;        
        $email->To = $user->Email;        
        $email->Template = 'Register';
        /**
        * Email params
        */
        $email->Params['DisplayedName'] = $user->Username;
        $email->Params['SiteUrl'] = Yii::app()->request->getBaseUrl(true);
        $email->Params['Email'] = $user->Email;
        $email->Params['Password'] = $rawPassword;
                
        $email->Params['ActivateUrl'] = Yii::app()->controller->createCmsUrl('user-activate', array('id' => $user->Id, 'code' => $user->ValidationCode), true);
              
        $emailParams['Email'] = $email;

        self::$result = EmailService::send($emailParams);        
        self::$result->ReturnedData['User'] = $user;
        
        return self::$result;
    }

    /**
    * Activate an account registered
    */
    public function activate($params)
    {
        // Get account info
        $id = self::getParam($params, 'id', 0);
        $code = self::getParam($params, 'code', null);
        // Check valid account
        $user = User::model()->findByPk($id);
        if (!empty($user)) {
            if ($user->ValidationCode != $code) {
                // Invalide account, the input validation code differs from in db
                self::$result->setFailStatus(ServiceResult::ERR_INVALID_DATA, Yii::t('User', 'USER_ACTIVATE_ACCOUNT_FAILED'));
            } else {
                // Update status to active
                $user->Status = User::STATUS_MEMBER;
                if ($user->update()) {
                    self::$result->ReturnedData['message'] = Yii::t('User', 'USER_ACTIVATE_ACCOUNT_SUCCESSFUL');
                } else {
                    self::$result->setFailStatus(ServiceResult::ERR_INVALID_DATA, Yii::t('User', 'USER_UPDATE_FAILED'));    
                }
            }
        }
        return self::$result;
    }
    
    /**
    * Authenticate an user
    *
    * @param mixed $params
    */
    public function login($params)
    {
        $user = new User();
        $user->scenario = 'login';
        if (isset($params['User'])) {
            $user->Email = $params['User']['Email'];
            $user->Password = $params['User']['Password'];   
        }
        
        $this->result->ReturnedData['User'] = $user;
        
        if(!$user->validate())
        {
            $this->result->fail(ServiceResult::ERR_INVALID_DATA, self::normalizeModelErrors($user->getErrors()));
            return $this->result;       
        }

        Yii::import('application.extensions.core.auth.UserIdentity');
        $ui = new UserIdentity($user->Email, $user->Password);
        $ui->authenticate();
        if ($ui->errorCode == UserIdentity::ERROR_NONE) {
            Yii::app()->user->login($ui);    
            if (($url = Yii::app()->user->returnUrl) != '')
                Yii::app()->controller->redirect($url);
            return $this->result;
        } else {
            $this->result->fail(ServiceResult::ERR_NONE, $ui->getErrorMessage($ui->errorCode));
            return $this->result;
        }
    }

    public function logout()
    {
        Yii::app()->user->logout();
        return self::$result;
    }
        
    /**
    * Update user account at BO
    *
    * @param mixed $params
    * @return ServiceResult
    */
    public function update($params)
    {
        $user = new User();
        self::getModel($params, $user, 'editAccount');
        if (self::$result->isFailed())
            return self::$result;

        //Encrypt password
        if ($user->Password != '') {
            $user->Password = md5($user->Password);
            $user->rePassword = md5($user->rePassword);
        }

        // Delete all current categories 
        UserCategory::model()->deleteAll("UserId={$user->Id}"); 
        
        // Update user  
        $user->setIsNewRecord(false);  
        if (!$user->update()) {
            self::$result->ReturnCode = ServiceResult::RETURN_FAILURE;
            self::$result->ErrorMessages = $user->getErrors();
        } 
        
        // Update categories 
        $categories = $params['Categories'];
        foreach ($categories as $categoryId) {
            $userCat = new UserCategory();
            $userCat->UserId = $user->Id;
            $userCat->CategoryId = $categoryId;
            if(!$userCat->save()) {
                self::$result->setFailStatus(ServiceResult::ERR_INVALID_DATA, self::normalizeModelErrors($userCat->getErrors()));
            }
        }
        return self::$result;
    }
    
    /**
    * Update account at FE
    * 
    * @param mixed $params
    * @return ServiceResult
    */
    public function edit($params)
    {
        $user = new User();
        self::getModel($params, $user, 'editAccount');
        if (self::$result->isFailed())
            return self::$result;

        $updatedFields = array( 'Username'  => $user->Username,
                                'Email'     => $user->Email);
        //Encrypt password
        if ($user->Password != '') {
            $user->Password = md5($user->Password);
            $user->rePassword = md5($user->rePassword);
            $updatedFields['Password'] = $user->Password;
        }

        // Update account
        if (!$user->updateByPk($user->Id, $updatedFields)) {
            self::$result->ReturnCode = ServiceResult::RETURN_FAILURE;
            self::$result->ErrorMessages = $user->getErrors();
        } 
        
        return self::$result;
    }
    
    /**
    * Check if email or username exists or not
    * 
    * @param mixed $params
    * - index email: email to check
    * - index username: username to check
    */
    public static function checkUsernameEmailExistence($params)
    {
        $email = self::getParam($params, 'email', '');
        $user = User::model()->find('Email=:email', array(':email'=>$email));
        if (! empty($user)) {
            self::$result->ReturnedData['emailExists'] = 1;
        } else {
            self::$result->ReturnedData['emailExists'] = 0;
        }
        
        $username = self::getParam($params, 'username', '');
        $user = User::model()->find('Username=:username', array(':username'=>$username));
        if (! empty($user)) {
            self::$result->ReturnedData['usernameExists'] = 1;
        } else {
            self::$result->ReturnedData['usernameExists'] = 0;
        }
        return self::$result;
    }
}
?>